/*!
* 
* Copyright (c) 2009 by yuqiang @ vcedu
* 
* Description:
*		This file contains the video interface which would be used outside the lib
*
* ChangeLog:
*		$Date$	$Rev$	$Author$
* 
*/	

#include "stdafx.h"

#include <miptime.h>
#include <miprawvideomessage.h>
#include <mipcompat.h>
#include <mipdebug.h>

#include <iostream>
#include <exception>

#include <log4cpp/Category.hh>

#include "videooutput.h"

#define VideoOuput_ERRSTR_NOTRUNNING				"Output thread is not running"
#define VideoOuput_ERRSTR_ALREADYRUNNING			"Output thread is already running"
#define VideoOuput_ERRSTR_CANTSTARTTHREAD			"Couldn't start the background thread"
#define VideoOuput_ERRSTR_BADMESSAGE				"Bad message"
#define VideoOuput_ERRSTR_PULLNOTSUPPORTED			"Pull not supported"

namespace librtp_video{

VideoOuput::VideoOuput() : MIPComponent("VideoOuput")
{
	int status;
	
	if ((status = m_lock.Init()) < 0)
	{
		throw std::exception();
	}
}

VideoOuput::~VideoOuput()
{
	shutdown();
}

bool VideoOuput::init()
{
	return true;
}

bool VideoOuput::shutdown()
{
	return true;
}

bool VideoOuput::push(const MIPComponentChain &chain, int64_t iteration, MIPMessage *pMsg)
{

	if (!(pMsg->getMessageType() == MIPMESSAGE_TYPE_VIDEO_RAW && pMsg->getMessageSubtype() == MIPRAWVIDEOMESSAGE_TYPE_YUV420P)) 
	{
		setErrorString(VideoOuput_ERRSTR_BADMESSAGE);
		return false;
	}

	MIPRawYUV420PVideoMessage *pVideoMsg = (MIPRawYUV420PVideoMessage *)pMsg;
	uint64_t id = pVideoMsg->getSourceID();
	
	m_lock.Lock();
	
	bool found = false;
	std::list<VideoWindow *>::const_iterator it;

	for (it = m_videoWindows.begin() ; !found && it != m_videoWindows.end() ; it++)
	{
		if ((*it)->getSourceID() == id)
		{
			found = true;
			(*it)->processRawVideoMessage(pVideoMsg);
		}
	}

	if(!found){
		VideoWindow* pVideoWindow = new VideoWindow();
		pVideoWindow->setSourceID(id);
		m_videoWindows.push_back(pVideoWindow);
		pVideoWindow->Start();
		pVideoWindow->processRawVideoMessage(pVideoMsg);
	}

	if (!found)
	{
		std::list<uint64_t>::const_iterator it;

		for (it = m_newIDs.begin() ; !found && it != m_newIDs.end() ; it++)
		{
			if ((*it) == id)
				found = true;
		}
		if (!found){
			m_newIDs.push_back(id);
		}
	}
	
	m_lock.Unlock();
	
	return true;
}

bool VideoOuput::pull(const MIPComponentChain &chain, int64_t iteration, MIPMessage **pMsg)
{
	setErrorString(VideoOuput_ERRSTR_PULLNOTSUPPORTED);
	return true;
}

}
